package com.gzhryc.shared_device.oem.code.profit.service;

import com.gzhryc.common.ClassTools;
import com.gzhryc.common.NumberTools;
import com.gzhryc.common.StringTools;
import com.gzhryc.common.exceptions.LogicException;
import com.gzhryc.common.logging.Logger;
import com.gzhryc.jdbc.Conditions;
import com.gzhryc.jdbc.MultiDBTools;
import com.gzhryc.shared_device.bxscn.code.dao.db.BXSCNOrder;
import com.gzhryc.shared_device.bxscn.code.dao.db.BXSCNShopOrder;
import com.gzhryc.shared_device.bxscn.code.dao.enums.BXSCNOrderEnum;
import com.gzhryc.shared_device.bxscn.code.dao.enums.BXSCNShopOrderEnum;
import com.gzhryc.shared_device.bxscn.code.dao.enums.EBXSCNCostMode;
import com.gzhryc.shared_device.cdb.code.dao.db.CDBOrder;
import com.gzhryc.shared_device.cdb.code.dao.enums.CDBOrderEnum;
import com.gzhryc.shared_device.cdcz.code.dao.db.CDCZOrder;
import com.gzhryc.shared_device.cdcz.code.dao.enums.CDCZOrderEnum;
import com.gzhryc.shared_device.oem.code.business.EBusinessType;
import com.gzhryc.shared_device.oem.code.device.EDeviceFunCode;
import com.gzhryc.shared_device.oem.code.place.dao.db.PlacePhysicalStore;
import com.gzhryc.shared_device.oem.code.profit.dao.BusinessOrderDao;
import com.gzhryc.shared_device.oem.code.profit.dao.db.BusinessOrder;
import com.gzhryc.shared_device.oem.code.profit.dao.enums.BusinessOrderEnum;
import com.gzhryc.shared_device.oem.code.profit.service.dto.BusinessOrderSearch;
import com.gzhryc.shared_device.pcl.code.dao.db.PCLOrder;
import com.gzhryc.shared_device.pcl.code.dao.enums.PCLOrderEnum;

import java.sql.SQLException;
import java.util.Date;
import java.util.List;

public class BusinessOrderService {

    static Logger log = Logger.getLogger(BusinessOrderService.class);

    public static BusinessOrderService self(Date date) {
        return MultiDBTools.getService(BusinessOrderService.class, date);
    }

    public static BusinessOrderService self(String jdbcKey,Date date) {
        return MultiDBTools.getService(jdbcKey, BusinessOrderService.class, date);
    }

    BusinessOrderDao dao;

    public BusinessOrderService(String jdbcKey,Date date) {
        dao = new BusinessOrderDao(jdbcKey,date);
    }

    public List<BusinessOrder> findBySearch(BusinessOrderSearch search, Integer pageNo, Integer pageLimit){
        Conditions conditions = dao.buildConditions(search);
        try {
            return dao.findByCondition(conditions,pageNo,pageLimit);
        } catch (SQLException e) {
            log.error(e.getMessage(),e);
        }
        return null;
    }

    public Long countBySearch(BusinessOrderSearch search){
        Conditions conditions = dao.buildConditions(search);
        try {
            return dao.count(conditions);
        } catch (SQLException e) {
            log.error(e.getMessage(),e);
        }
        return 0L;
    }

    public List<BusinessOrder> findByTradeNoList(List<String> tradeNoList){
        if(tradeNoList != null && tradeNoList.size() > 0){
            Conditions conditions = new Conditions(BusinessOrder.class);
            conditions.and().in("tradeNo",tradeNoList);
            try {
                return dao.findByCondition(conditions);
            } catch (SQLException e) {
                log.error(e.getMessage(),e);
            }
        }
        return null;
    }

    public BusinessOrder getByTradeNo(String tradeNo){
        try {
            return dao.getById(tradeNo);
        } catch (SQLException e) {
            log.error(e.getMessage(),e);
        }
        return null;
    }

    public boolean cancel(String tradeNo,Date cancelDate){
        if(StringTools.isNotBlank(tradeNo) && cancelDate != null) {
            BusinessOrder businessOrder = new BusinessOrder();
            businessOrder.setTradeNo(tradeNo);
            businessOrder.setCancelDate(cancelDate);

            try {
                if (dao.updateNotNull(businessOrder) > 0) {
                    return true;
                }
            } catch (SQLException e) {
                log.error(e.getMessage(), e);
            }
        }
        return false;
    }

    public BusinessOrder create(CDCZOrder deviceOrder, PlacePhysicalStore physicalStore) throws LogicException {
        BusinessOrder temp = getByTradeNo(deviceOrder.getTradeNo());
        if(temp != null){
            BusinessOrder updateEntity = null;
            if(!temp.getIncomeMoney().equals(deviceOrder.getIncomeMoney())){
                updateEntity = new BusinessOrder();
                updateEntity.setTradeNo(temp.getTradeNo());
                updateEntity.setMoney(deviceOrder.getMoney());
                updateEntity.setIncomeMoney(deviceOrder.getIncomeMoney());
                updateEntity.setDiscountMoney(deviceOrder.getDiscountMoney());
                updateEntity.setPayMoney(deviceOrder.getPayMoney());
                updateEntity.setWalletMoney(deviceOrder.getWalletMoney());

                Long refundMoney = temp.getWalletRefundMoney() + NumberTools.changeMoneyLi(NumberTools.changeMoney(temp.getRefundMoney()));
                if(refundMoney > 0){
                    //业务订单的订单金额包含退款金额
                    updateEntity.setMoney(deviceOrder.getMoney() + refundMoney);
                }
            }

            if(updateEntity != null){
                try {
                    if(dao.updateNotNull(updateEntity) > 0){
                        temp = getByTradeNo(deviceOrder.getTradeNo());
                    }
                } catch (SQLException e) {
                    log.error(e.getMessage(), e);
                }
            }
            return temp;
        }else {
            BusinessOrder businessOrder = ClassTools.copy(new BusinessOrder(), deviceOrder);
            businessOrder.setDeviceFunCode(EDeviceFunCode.CDCZ.index());
            businessOrder.setBusinessType(EBusinessType.CDCZ.index());
            businessOrder.setDeviceSn(deviceOrder.getChargeSocketSn());
            businessOrder.setMemberId(deviceOrder.getMemberId());
            businessOrder.setMemberName(deviceOrder.getMemberName());
            businessOrder.setCostModeName(deviceOrder.getCostModeName());  //无属性无法自动拷贝

            businessOrder.setPlaceId(physicalStore.getId());
            businessOrder.setPlaceName(physicalStore.getName());
            businessOrder.setPlaceUserId(physicalStore.getUserId());        //网点代理ID
            businessOrder.setProvince(physicalStore.getProvince());
            businessOrder.setCity(physicalStore.getCity());
            businessOrder.setCityArea(physicalStore.getCityArea());
            businessOrder.setAreaCode(physicalStore.getAreaCode());

            if (CDCZOrderEnum.State.Finish.index().equals(deviceOrder.getState()) 
            		|| CDCZOrderEnum.State.Close.index().equals(deviceOrder.getState())) {
                businessOrder.setIncomeMoney(deviceOrder.getIncomeMoney());
            } else {
                businessOrder.setIncomeMoney(0L);
            }
            try {
                if(dao.insert(businessOrder) > 0){
                    return businessOrder;
                }
            } catch (SQLException e) {
                log.error(e.getMessage(), e);
            }
        }

        return null;
    }

    public BusinessOrder create(CDBOrder deviceOrder, PlacePhysicalStore physicalStore)throws LogicException {
        BusinessOrder temp = getByTradeNo(deviceOrder.getTradeNo());
        if(temp != null) {
            //重新判断金额
            BusinessOrder updateEntity = null;
            if(!temp.getIncomeMoney().equals(deviceOrder.getIncomeMoney())){
                updateEntity = new BusinessOrder();
                updateEntity.setTradeNo(temp.getTradeNo());
                updateEntity.setMoney(deviceOrder.getMoney());
                updateEntity.setIncomeMoney(deviceOrder.getIncomeMoney());
                updateEntity.setDiscountMoney(deviceOrder.getDiscountMoney());
                updateEntity.setPayMoney(deviceOrder.getPayMoney());
                updateEntity.setWalletMoney(deviceOrder.getWalletMoney());

                Long refundMoney = temp.getWalletRefundMoney() + NumberTools.changeMoneyLi(NumberTools.changeMoney(temp.getRefundMoney()));
                if(refundMoney > 0){
                    //业务订单的订单金额包含退款金额
                    updateEntity.setMoney(deviceOrder.getMoney() + refundMoney);
                }
            }

            if(updateEntity != null){
                try {
                    if(dao.updateNotNull(updateEntity) > 0){
                        temp = getByTradeNo(deviceOrder.getTradeNo());
                    }
                } catch (SQLException e) {
                    log.error(e.getMessage(), e);
                }
            }
            return temp;
        }else{
            BusinessOrder businessOrder = ClassTools.copy(new BusinessOrder(), deviceOrder);
            businessOrder.setDeviceFunCode(EDeviceFunCode.CDB.index());
            businessOrder.setBusinessType(EBusinessType.CDB.index());
            businessOrder.setDeviceSn(deviceOrder.getLeaseChargingCabinetSn());
            businessOrder.setSlotNum(deviceOrder.getLeaseSlotNum());
            businessOrder.setMemberId(deviceOrder.getMemberId());
            businessOrder.setMemberName(deviceOrder.getMemberName());
            businessOrder.setCostModeName(deviceOrder.getCostModeName());  //无属性无法自动拷贝

            businessOrder.setPlaceId(physicalStore.getId());
            businessOrder.setPlaceName(physicalStore.getName());
            businessOrder.setPlaceUserId(physicalStore.getUserId());        //网点代理ID
            businessOrder.setProvince(physicalStore.getProvince());
            businessOrder.setCity(physicalStore.getCity());
            businessOrder.setCityArea(physicalStore.getCityArea());
            businessOrder.setAreaCode(physicalStore.getAreaCode());

            if (CDBOrderEnum.State.RevertFinish.index().equals(deviceOrder.getState()) 
            		|| CDBOrderEnum.State.Close.index().equals(deviceOrder.getState())) {
                businessOrder.setIncomeMoney(deviceOrder.getIncomeMoney());
            } else {
                businessOrder.setIncomeMoney(0L);
            }

            try {
                if (dao.insert(businessOrder) > 0) {
                    return businessOrder;
                }
            } catch (SQLException e) {
                log.error(e.getMessage(), e);
            }
        }
        return null;
    }

    public BusinessOrder create(BXSCNShopOrder deviceOrder, PlacePhysicalStore physicalStore) throws LogicException {
        BusinessOrder temp = getByTradeNo(deviceOrder.getTradeNo());
        if(temp != null) {
            //重新判断金额
            BusinessOrder updateEntity = null;
            if(!temp.getIncomeMoney().equals(deviceOrder.getIncomeMoney())){
                updateEntity = new BusinessOrder();
                updateEntity.setTradeNo(temp.getTradeNo());
                updateEntity.setMoney(deviceOrder.getMoney());
                updateEntity.setIncomeMoney(deviceOrder.getIncomeMoney());
                updateEntity.setDiscountMoney(deviceOrder.getDiscountMoney());
                updateEntity.setPayMoney(deviceOrder.getPayMoney());
                updateEntity.setWalletMoney(deviceOrder.getWalletMoney());

                Long refundMoney = temp.getWalletRefundMoney() + NumberTools.changeMoneyLi(NumberTools.changeMoney(temp.getRefundMoney()));
                if(refundMoney > 0){
                    //业务订单的订单金额包含退款金额
                    updateEntity.setMoney(deviceOrder.getMoney() + refundMoney);
                }
            }

            if(updateEntity != null){
                try {
                    if(dao.updateNotNull(updateEntity) > 0){
                        temp = getByTradeNo(deviceOrder.getTradeNo());
                    }
                } catch (SQLException e) {
                    log.error(e.getMessage(), e);
                }
            }
            return temp;
        }else {
            BusinessOrder businessOrder = ClassTools.copy(new BusinessOrder(), deviceOrder);
            businessOrder.setDeviceFunCode(EDeviceFunCode.BXSCN.index());
            businessOrder.setBusinessType(EBusinessType.BXSCN_SHOP.index());
            if (StringTools.isNotBlank(deviceOrder.getPortableBatterySn())) {
                businessOrder.setDeviceSn(deviceOrder.getPortableBatterySn());
            } else {
                businessOrder.setDeviceSn("0");     //没有租借成功时，默认
            }
            businessOrder.setMemberId(deviceOrder.getMemberId());
            businessOrder.setMemberName(deviceOrder.getMemberName());
            businessOrder.setCostMode(EBXSCNCostMode.Deposit.index());
            businessOrder.setCostModeName(EBXSCNCostMode.Deposit.note());  //无属性无法自动拷贝

            businessOrder.setPlaceId(physicalStore.getId());
            businessOrder.setPlaceName(physicalStore.getName());
            businessOrder.setPlaceUserId(physicalStore.getUserId());        //网点代理ID
            businessOrder.setProvince(physicalStore.getProvince());
            businessOrder.setCity(physicalStore.getCity());
            businessOrder.setCityArea(physicalStore.getCityArea());
            businessOrder.setAreaCode(physicalStore.getAreaCode());

            if (BXSCNShopOrderEnum.State.RevertFinish.index().equals(deviceOrder.getState())
            		|| BXSCNShopOrderEnum.State.RevertClose.index().equals(deviceOrder.getState())
            		|| BXSCNShopOrderEnum.State.LeaseClose.index().equals(deviceOrder.getState())
            		|| BXSCNShopOrderEnum.State.Close.index().equals(deviceOrder.getState())) {
                businessOrder.setIncomeMoney(deviceOrder.getIncomeMoney());
            } else {
                businessOrder.setIncomeMoney(0L);
            }

            try {
                if (dao.insert(businessOrder) > 0) {
                    return businessOrder;
                }
            } catch (SQLException e) {
                log.error(e.getMessage(), e);
            }
        }
        return null;
    }

    public BusinessOrder create(BXSCNOrder deviceOrder, PlacePhysicalStore physicalStore)throws LogicException {
        BusinessOrder temp = getByTradeNo(deviceOrder.getTradeNo());
        if(temp != null) {
            //重新判断金额
            BusinessOrder updateEntity = null;
            if(!temp.getIncomeMoney().equals(deviceOrder.getIncomeMoney())){
                updateEntity = new BusinessOrder();
                updateEntity.setTradeNo(temp.getTradeNo());
                updateEntity.setMoney(deviceOrder.getMoney());
                updateEntity.setIncomeMoney(deviceOrder.getIncomeMoney());
                updateEntity.setDiscountMoney(deviceOrder.getDiscountMoney());
                updateEntity.setPayMoney(deviceOrder.getPayMoney());
                updateEntity.setWalletMoney(deviceOrder.getWalletMoney());

                Long refundMoney = temp.getWalletRefundMoney() + NumberTools.changeMoneyLi(NumberTools.changeMoney(temp.getRefundMoney()));
                if(refundMoney > 0){
                    //业务订单的订单金额包含退款金额
                    updateEntity.setMoney(deviceOrder.getMoney() + refundMoney);
                }
            }

            if(updateEntity != null){
                try {
                    if(dao.updateNotNull(updateEntity) > 0){
                        temp = getByTradeNo(deviceOrder.getTradeNo());
                    }
                } catch (SQLException e) {
                    log.error(e.getMessage(), e);
                }
            }
            return temp;
        }else {
            BusinessOrder businessOrder = ClassTools.copy(new BusinessOrder(), deviceOrder);
            businessOrder.setDeviceFunCode(EDeviceFunCode.BXSCN.index());
            businessOrder.setBusinessType(EBusinessType.BXSCN.index());
            businessOrder.setDeviceSn(deviceOrder.getLeaseDeviceSn());
            businessOrder.setSlotNum(deviceOrder.getLeaseSlotNum());
            businessOrder.setMemberId(deviceOrder.getMemberId());
            businessOrder.setMemberName(deviceOrder.getMemberName());
            businessOrder.setCostModeName(deviceOrder.getCostModeName());  //无属性无法自动拷贝

            businessOrder.setPlaceId(physicalStore.getId());
            businessOrder.setPlaceName(physicalStore.getName());
            businessOrder.setPlaceUserId(physicalStore.getUserId());        //网点代理ID
            businessOrder.setProvince(physicalStore.getProvince());
            businessOrder.setCity(physicalStore.getCity());
            businessOrder.setCityArea(physicalStore.getCityArea());
            businessOrder.setAreaCode(physicalStore.getAreaCode());

            if (BXSCNOrderEnum.State.RevertFinish.index().equals(deviceOrder.getState())
            		|| BXSCNOrderEnum.State.Close.index().equals(deviceOrder.getState())) {
                businessOrder.setIncomeMoney(deviceOrder.getIncomeMoney());
            } else {
                businessOrder.setIncomeMoney(0L);
            }

            try {
                if (dao.insert(businessOrder) > 0) {
                    return businessOrder;
                }
            } catch (SQLException e) {
                log.error(e.getMessage(), e);
            }
        }
        return null;
    }

    public BusinessOrder create(PCLOrder deviceOrder, PlacePhysicalStore physicalStore)throws LogicException {
        BusinessOrder temp = getByTradeNo(deviceOrder.getTradeNo());
        if(temp != null) {
            //重新判断金额
            BusinessOrder updateEntity = null;
            if(!temp.getIncomeMoney().equals(deviceOrder.getIncomeMoney())){
                updateEntity = new BusinessOrder();
                updateEntity.setTradeNo(temp.getTradeNo());
                updateEntity.setMoney(deviceOrder.getMoney());
                updateEntity.setIncomeMoney(deviceOrder.getIncomeMoney());
                updateEntity.setDiscountMoney(deviceOrder.getDiscountMoney());
                updateEntity.setPayMoney(deviceOrder.getPayMoney());
                updateEntity.setWalletMoney(deviceOrder.getWalletMoney());

                Long refundMoney = temp.getWalletRefundMoney() + NumberTools.changeMoneyLi(NumberTools.changeMoney(temp.getRefundMoney()));
                if(refundMoney > 0){
                    //业务订单的订单金额包含退款金额
                    updateEntity.setMoney(deviceOrder.getMoney() + refundMoney);
                }
            }

            if(updateEntity != null){
                try {
                    if(dao.updateNotNull(updateEntity) > 0){
                        temp = getByTradeNo(deviceOrder.getTradeNo());
                    }
                } catch (SQLException e) {
                    log.error(e.getMessage(), e);
                }
            }
            return temp;
        }else {
            BusinessOrder businessOrder = ClassTools.copy(new BusinessOrder(), deviceOrder);
            businessOrder.setDeviceFunCode(EDeviceFunCode.PCL.index());
            businessOrder.setBusinessType(EBusinessType.PCL.index());
            businessOrder.setDeviceSn(deviceOrder.getChargingCableSn());
            businessOrder.setSlotNum(1);        //默认1
            businessOrder.setMemberId(deviceOrder.getMemberId());
            businessOrder.setMemberName(deviceOrder.getMemberName());
            businessOrder.setCostModeName(deviceOrder.getCostModeName());  //无属性无法自动拷贝

            businessOrder.setPlaceId(physicalStore.getId());
            businessOrder.setPlaceName(physicalStore.getName());
            businessOrder.setPlaceUserId(physicalStore.getUserId());        //网点代理ID
            businessOrder.setProvince(physicalStore.getProvince());
            businessOrder.setCity(physicalStore.getCity());
            businessOrder.setCityArea(physicalStore.getCityArea());
            businessOrder.setAreaCode(physicalStore.getAreaCode());

            if (PCLOrderEnum.State.Finish.index().equals(deviceOrder.getState()) 
            		|| PCLOrderEnum.State.Close.index().equals(deviceOrder.getState())) {
                businessOrder.setIncomeMoney(deviceOrder.getIncomeMoney());
            } else {
                businessOrder.setIncomeMoney(0L);
            }

            try {
                if (dao.insert(businessOrder) > 0) {
                    return businessOrder;
                }
            } catch (SQLException e) {
                log.error(e.getMessage(), e);
            }
        }
        return null;
    }

    public boolean incomeDivideLock(String tradeNo,Long incomeMoney){
        Conditions conditions = new Conditions(BusinessOrder.class);
        conditions.and().is("tradeNo",tradeNo);
        conditions.and().is("divideState", BusinessOrderEnum.DivideState.Wait.index())
                .or().is("divideState",BusinessOrderEnum.DivideState.Fail.index());

        BusinessOrder updateEntity = new BusinessOrder();
        updateEntity.setDivideState(BusinessOrderEnum.DivideState.Executing.index());
        updateEntity.setIncomeMoney(incomeMoney);

        try {
            return dao.updateNotNull(updateEntity,conditions) > 0;
        } catch (SQLException e) {
            log.error(e.getMessage(),e);
        }
        return false;
    }

    public boolean incomeCancelLock(String tradeNo){
        Conditions conditions = new Conditions(BusinessOrder.class);
        conditions.and().is("tradeNo",tradeNo);
        conditions.and().is("divideState", BusinessOrderEnum.DivideState.Finish.index());

        BusinessOrder updateEntity = new BusinessOrder();
        updateEntity.setDivideState(BusinessOrderEnum.DivideState.CancelExecuting.index());

        try {
            return dao.updateNotNull(updateEntity,conditions) > 0;
        } catch (SQLException e) {
            log.error(e.getMessage(),e);
        }
        return false;
    }

    public boolean incomeDivideFinish(String tradeNo){
        Conditions conditions = new Conditions(BusinessOrder.class);
        conditions.and().is("tradeNo",tradeNo);
        conditions.and().is("divideState", BusinessOrderEnum.DivideState.Executing.index());

        BusinessOrder updateEntity = new BusinessOrder();
        updateEntity.setDivideState(BusinessOrderEnum.DivideState.Finish.index());
        updateEntity.setDivideDate(new Date());

        try {
            return dao.updateNotNull(updateEntity,conditions,"divide_error") > 0;
        } catch (SQLException e) {
            log.error(e.getMessage(),e);
        }
        return false;
    }

    public boolean incomeDivideFail(String tradeNo,String divideError){
        Conditions conditions = new Conditions(BusinessOrder.class);
        conditions.and().is("tradeNo",tradeNo);
        conditions.and().is("divideState", BusinessOrderEnum.DivideState.Executing.index());

        BusinessOrder updateEntity = new BusinessOrder();
        updateEntity.setDivideState(BusinessOrderEnum.DivideState.Fail.index());
        updateEntity.setDivideError(divideError);

        try {
            return dao.updateNotNull(updateEntity,conditions) > 0;
        } catch (SQLException e) {
            log.error(e.getMessage(),e);
        }
        return false;
    }

    public boolean incomeCancelFinish(String tradeNo){
        Conditions conditions = new Conditions(BusinessOrder.class);
        conditions.and().is("tradeNo",tradeNo);
        conditions.and().is("divideState", BusinessOrderEnum.DivideState.CancelExecuting.index());

        BusinessOrder updateEntity = new BusinessOrder();
        updateEntity.setDivideState(BusinessOrderEnum.DivideState.Wait.index());
        updateEntity.setCancelDate(new Date());

        try {
            return dao.updateNotNull(updateEntity,conditions) > 0;
        } catch (SQLException e) {
            log.error(e.getMessage(),e);
        }
        return false;
    }

    public boolean incomeCancelFail(String tradeNo){
        Conditions conditions = new Conditions(BusinessOrder.class);
        conditions.and().is("tradeNo",tradeNo);
        conditions.and().is("divideState", BusinessOrderEnum.DivideState.CancelExecuting.index());

        BusinessOrder updateEntity = new BusinessOrder();
        updateEntity.setDivideState(BusinessOrderEnum.DivideState.Finish.index());

        try {
            return dao.updateNotNull(updateEntity,conditions) > 0;
        } catch (SQLException e) {
            log.error(e.getMessage(),e);
        }
        return false;
    }
}
